package com.lovose.common;

import java.io.Serializable;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;


public class SupportDao <T, PK extends Serializable> implements Dao<T, PK>{
	private static SessionFactory sessionFactory;

	public static SessionFactory getSessionFactory() {
		if (sessionFactory == null) {
			sessionFactory = new Configuration().configure()
					.buildSessionFactory();
		}
		return sessionFactory;
	}
	public static void close() {
		sessionFactory.close();
	}

	protected Session getSession() {
		return getSessionFactory().openSession();
	}

	protected void rollback(Session session) {
		if (session != null) {
			session.getTransaction().rollback();
		}
	}

	protected void close(Session session) {
		if (session != null) {
			session.close();
		}
	}

	@SuppressWarnings("unchecked")
	protected Class entityClass;

	@Override
	public void create(T entity) {
		Session session = null;

		try {
			session = this.getSession();
			session.getTransaction().begin();
			session.save(entity);
			session.getTransaction().commit();
		} catch (RuntimeException e) {
			this.rollback(session);
			throw e;
		} finally {
			this.close(session);
		}
	}

	@Override
	public void delete(T entity) {
		Session session = null;

		try {
			session = this.getSession();
			session.getTransaction().begin();
			session.delete(entity);
			session.getTransaction().commit();
		} catch (RuntimeException e) {
			this.rollback(session);
			throw e;
		} finally {
			this.close(session);
		}
	}

	@SuppressWarnings("unchecked")
	@Override
	public T get(PK id) {
		Session session = null;

		try {
			session = this.getSession();
			session.getTransaction().begin();
			T entity = (T) session.get(this.entityClass, id);
			session.getTransaction().commit();
			return entity;
		} catch (RuntimeException e) {
			this.rollback(session);
			throw e;
		} finally {
			this.close(session);
		}
	}

	@Override
	public void update(T entity) {
		Session session = null;

		try {
			session = this.getSession();
			session.getTransaction().begin();
			session.update(entity);
			session.getTransaction().commit();
		} catch (RuntimeException e) {
			this.rollback(session);
			throw e;
		} finally {
			this.close(session);
		}
	}
	@Override
	public void saveOrUpdate(T entity) {
		Session session = null;

		try {
			session = this.getSession();
			session.getTransaction().begin();
			session.saveOrUpdate(entity);
			session.getTransaction().commit();
		} catch (RuntimeException e) {
			this.rollback(session);
			throw e;
		} finally {
			this.close(session);
		}
		
	}
}
